import socket from '@ohos.net.socket';
import { Param } from './Param'

const TAG = '[TcpClient]'

export class TcpClient {
    private oppositeIp: string = Param.relayIp
    private oppositeIpPort: string = '50000'

    public tcp: socket.TCPSocket = null
    static instance: TcpClient | null = null
    static getInstance() {
        if (!TcpClient.instance) {
            TcpClient.instance = new TcpClient()
        }
        return TcpClient.instance;
    }
    constructor() {
        this.tcp = socket.constructTCPSocketInstance();
    }
    onError(callback?){
        this.tcp.on('error', err => {
            console.log(TAG + 'onError ' + JSON.stringify(err))
            this.connectTcp()
            // this.closeUdp(()=>{
            //   this.bindUdp()
            // })
        });
    }

    connectTcp(){
        return new Promise((resolve,reject)=>{
            let promise = this.tcp.connect({ address: {address: this.oppositeIp, port:  parseInt(this.oppositeIpPort), family: 1} , timeout: 6000});
            promise.then(() => {
                this.tcp.setExtraOptions({
                    keepAlive: true,
                    // OOBInline: true,
                    // TCPNoDelay: true,
                    // socketLinger: { on:true, linger:10 },
                    // receiveBufferSize: 1000,
                    // sendBufferSize: 1000,
                    // reuseAddress: true,
                    // socketTimeout: 3000,
                },err => {
                    if (err) {
                        return;
                    }
                });
                console.log(TAG + 'connectTcp suc')
                resolve(true)
            }).catch(err => {
                console.log(TAG + 'connectTcp fail')
                resolve(false)
            });
        })
    }

    sendMsg(msg: string) {
        return new Promise((reslove,reject)=>{
            let promise = this.tcp.send({
                data:msg
            });
            promise.then(() => {
                console.log(TAG + 'sendMsg suc')
                reslove(true)
            }).catch(err => {
                console.log(TAG + 'sendMsg fail')
                reslove(false)
            });
        })
    }

    onMessage(callback) {
        this.tcp.on('message', value => {
            if (value) {
                let messageView = ''
                for (let i: number = 0; i < value.message.byteLength; i++) {
                  let uint8Array = new Uint8Array(value.message)
                  let messages = uint8Array[i]
                  let message = String.fromCharCode(messages);
                  messageView += message;
                }
                // this.relayStatus = JSON.parse(messageView)
                console.log(TAG + 'onMessage ' + JSON.stringify(messageView))
                const index = messageView.indexOf(Param.lightTag)
                const result = messageView.slice(index+5, index+6)
                console.log(TAG + 'onMessage ' + 'result: ' + result + " index: " + index)
                callback(result)
            } else{
                console.log(TAG + 'onMessage error')
                callback('')
            }
        });

    }
    offTcp(callback) {
       this.tcp.off('message', callback);
    }
    closeTcp(callback) {
        return new Promise((reslove,reject)=>{
            let promise = this.tcp.close();
            promise.then(() => {
                console.log(TAG + 'close success');
                callback()
                reslove(true)
            }).catch(err => {
                console.log(TAG + 'close fail');
                reslove(false)
            });
        })
    }
}